Executor 框架 - 线程池

概念

线程池(Thread Pool)是一种线程使用模式。当线程使用不当,创建过多时会带来调度的开销,进而影响缓存局部性和整体性能。而线程池维护着若干个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。

重要成员

在 Java 中,线程池一般都是通过 ThreadPoolExecutor 来构建的,下面将介绍 ThreadPoolExecutor 的构造函数部分。

1
2
3
4
5
6
7
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
参数 作用
corePoolSize 线程池中所保存的核心线程数。线程池启动时默认是空的,只有任务来临时才会创建线程以处理请求。在 corePoolSize 范围内已创建的线程即使处于空闲状态,除非设置了 allowCoreThreadTimeOut,否则不会被销毁
maximumPoolSize 线程池允许创建的最大线程数。
keepAliveTime 当线程池中的线程超过了 corePoolSize 的范围时,终止过多的空闲线程的时间
unit keepAliveTime 的时间单位
workQueue 用于容纳所有待执行的任务的工作队列。该工作队列只能够容纳实通过 execute() 方法提交的实现 Runnable 接口的任务
threadFactory 用于 executor 如何创建一个线程(一般使用默认线程工厂DefaultThreadFactory)
handler 当线程池与工作队列的容量已满时,任务提交被拒绝时所采取的拒绝策略。

工作流程

以下流程为向线程池中正常提交任务时的基本流程:

  1. 线程池判断核心线程池(corePoolSize)里的线程是否都在执行任务,如果不是,则创建一个新的工作线程(或复用一个工作线程)来执行任务。如果核心线程池里的线程都在执行任务,则执行第二步。
  2. 线程池判断工作队列(workQueue)是否已经满了。如果工作队列没有满,则将新提交的任务存储到工作队列中,等待被调度执行。如果工作队列已满,则执行第三步。
  3. 线程池判断线程池的线程是否已经满了(maximumPoolSize)。如果没有,则创建一个新的工作线程来执行任务。如果已经满了,则根据线程池的拒绝策略来处理该任务。

以上两图均来自于这篇博客Java线程池(ThreadPoolExecutor)原理分析与使用 - 孙_悟__空

拒绝策略

线程池中已经定义了四种任务提交的拒绝策略(以下策略我都贴出源码部分,怕翻译有问题):

  • AbortPolicy :不执行任务,并直接抛出一个运行时异常。
1
A handler for rejected tasks that throws a RejectedExecutionException
  • DiscardPolicy :(silently)直接抛弃任务,其内部实现是一个空方法。
1
A handler for rejected tasks that silently discards the rejected task.
  • DiscardOldestPolicy : 从工作队列中抛弃最老的未处理的任务,并尝试重新执行该任务。
1
2
3
A handler for rejected tasks that discards the oldest unhandled request 
and then retries {@code execute}, unless the executor is shut down, in
which case the task is discarded.
  • CallerRunsPolicy : 线程池直接创建一个 calling 线程来执行任务。
1
2
3
A handler for rejected tasks that runs the rejected task directly in the 
calling thread of the {@code execute} method, unless the executor has
been shut down, in which case the task is discarded.

参考资料

线程池 - 维基百科,自由的百科全书

Java:多线程,线程池,ThreadPoolExecutor详解

Java线程池(ThreadPoolExecutor)原理分析与使用